import time
import threading
from iClouds.libs import header_has_guuid
from iClouds.level import level_data, has_level
from iClouds.unity import (
    has_zombie,
    zombie,
    has_jewelry,
    # jewelry,
    has_plant,
    plant,
    shoping,
    jewelry_data,
    moneyStar,
    fireSlug,
)
import random


class roomManager(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.isRun = True  # 是否运行
        self.sleep = 3  # 等待就绪秒数
        self.name = name
        self.player = set()  # 玩家合集
        self.level = 1  # 当前关卡
        self.money = 100  # 金币
        self.max_player = 4  # 最大玩家数
        self.gap = 11  # 地图长度
        self.min_gap = (80, 80)  # 最小单元像素
        self.map = has_level(1)  # 关卡地图

        self.guid = header_has_guuid()
        self.status = "wait"  # 房间状态: wait | lock | fight | report
        self.hp = 100  # 自己的生命
        self.ontime = None  # 开始时间
        self.last = None  # 上次刷怪
        self.over = None  # 结束时间
        self.batch = 0  # 刷怪批次
        self.plant = set()  # 植物合集
        self.zombie = set()  # 僵尸合集
        self.jewelry = set()  # 道具合集
        self.card = set()  #  卡片合集
        self.sunlight = set()  # 星星合集
        self.slug = set()  # 子弹类
        # 初始化
        # self.initialization()

    def stop(self):
        self.isRun = False

    def initialization(self, level=-1):
        """初始化"""
        unit = self.plant
        unit |= self.zombie
        unit |= self.jewelry
        unit |= self.card
        unit |= self.sunlight
        unit |= self.slug
        for i in unit:
            i.stop()
            i.join()
        self.guid = header_has_guuid()
        self.status = "wait"  # 房间状态: wait | lock | fight | report
        self.hp = 100  # 自己的生命
        self.ontime = None  # 开始时间
        self.last = None  # 上次刷怪
        self.over = None  # 结束时间
        self.batch = 0  # 当前刷怪批次
        self.plant = set()  # 植物合集
        self.zombie = set()  # 僵尸合集
        self.jewelry = set()  # 道具合集
        self.card = set()  #  卡片合集
        self.sunlight = set()  # 星星合集
        self.slug = set()  # 子弹类

        if level < 0:
            self.level += 1
        else:
            self.level = level

        self.map = has_level(self.level)
        self.gap = self.map["gap"]  # 地图长度
        self.min_gap = self.map["min_area"]  # 最小单元像素
        print("\r战场初始化完成...")

    def run(self):
        print(f"创建房间 {self.name}")
        while self.isRun:
            time.sleep(0.2)
            if self.status == "wait":
                if self.checkPlayerStatus():
                    self.status = "lock"
                    self.changePlayerStatus("lock")
                    self.alertAIring(
                        {
                            "act": "lock",
                            "guid": "room",
                            "code": 200,
                            "data": self.sleep,
                            "maps": self.map,
                        }
                    )
            elif self.status == "lock":
                for i in range(self.sleep):
                    self.alertAIring(
                        {
                            "act": "lock",
                            "guid": "room",
                            "code": 200,
                            "data": self.sleep - i,
                        }
                    )
                    time.sleep(1)

                # 发送初始金币
                self.alertAIring(
                    {"act": "money", "guid": "room", "code": 200, "data": self.money}
                )
                time.sleep(0.5)
                # 发送地图
                self.alertAIring(
                    {
                        "act": "maps",
                        "guid": "room",
                        "code": 200,
                        "data": self.map,
                    }
                )
                time.sleep(0.5)
                # 开始战斗
                self.status = "fight"
                self.ontime = time.time()
                self.last = time.time()
                self.changePlayerStatus("fight")
                self.alertAIring({"act": "fight", "guid": "room", "code": 200})
                time.sleep(0.5)
                # 加载商城卡片
                self.enableCardShop()
                time.sleep(0.5)
                # 刷新1个僵尸
                z = zombie(self)
                z.setAttrs(has_zombie(1))
                z.setPoint((self.gap, 3))
                z.start()
                self.zombie.add(z)

            elif self.status == "fight":
                if not len(self.player):
                    print("结束关卡:逃跑")
                    self.over = time.time()
                    self.status = "wait"
                    self.initialization(1)
                elif self.hp <= 0:
                    print("结束关卡:失败")
                    self.over = time.time()
                    self.alertAIring({"act": "lose", "guid": "room"})
                    self.status = "wait"
                    self.initialization(self.level)
                elif len(self.zombie) == 0:
                    print("结束关卡:胜利")
                    self.over = time.time()
                    self.alertAIring({"act": "win", "guid": "room"})
                    self.status = "wait"
                    self.initialization()
                else:  # 批次刷怪
                    if time.time() - self.last > self.map[
                        "interval"
                    ] and self.batch < len(self.map["max"]):
                        self.enableAiPlayer()
            elif self.status == "report":
                pass
            else:
                pass

    def alertAIring(self, data):
        """广播消息"""
        for player in self.player:
            player.snedMessage(data)

    def load_level(self):
        """加载关卡"""
        self.level += 1
        self.map = has_level(self.level)
        self.batch = 0
        return self.map

    def enableCardShop(self):
        """加载卡片"""
        shop = self.map["card"]
        idx = 0
        for i in set(shop):
            x = has_plant(i)
            c = shoping(self)
            c.setAttrs(x)
            c.setPoint(idx)
            c.start()
            self.card.add(c)
            idx += 1

    def enableAiPlayer(self):
        """批次刷怪"""
        print("当前批次:", self.batch, "/", len(self.map["max"]))
        # 加载轨道刷怪范围的列表
        attacker = self.map["zombie"]
        # 重写
        for track in range(len(attacker)):  # 轨道号
            if not attacker[track]:
                continue
            # 创建道具
            dj = [
                random.choice(jewelry_data)
                for j in range(self.map["jewelry"][self.batch])
            ]
            # 创建僵尸
            for i in range(self.map["max"][self.batch]):
                # 怪物ID
                zl = random.choice(attacker[track])
                wt = self.creatZombie(zl, track)
                if len(dj):
                    x = dj.pop()
                    wt.setTools(x)
                self.zombie.add(wt)
        # 更新批次
        self.batch += 1

    def creatZombie(self, idx, track):
        """创建僵尸: 怪的ID, 轨道号"""
        zom = has_zombie(idx)
        wt = zombie(self)
        wt.setAttrs(zom)
        wt.setPoint((self.gap, track))
        wt.start()
        return wt

    def checkPlayerStatus(self):
        """检测玩家状态是否就绪"""
        if not len(self.player):
            return False
        state = True
        for i in self.player:
            if i.status == "wait":
                state = False
        return state

    def changePlayerStatus(self, state):
        """修改玩家状态"""
        for i in self.player:
            i.status = state

    def buyCardFromPlayer(self, data):
        """用户购买卡片"""
        # data = {
        #     "act": "buyCard",
        #     "guid": "5567b4cc-7245-11ef-a089-0242ac120006",
        #     "data": {
        #         "id": 1,
        #         "name": "太阳花",
        #         "guid": "5a847440-7245-11ef-a22f-0242ac120006",
        #         "point": [0, 3],
        #     },
        # }
        # 检测空位
        for plt in self.plant:
            if plt.point == data["data"]["point"]:
                return
        newPlant = has_plant(data["data"]["id"])
        if self.money > newPlant["cost"]:
            self.money -= newPlant["cost"]  # 扣费
            self.alertAIring(
                {"act": "money", "guid": "room", "code": 200, "data": self.money}
            )
            # 创建植物
            zw = plant(self)
            zw.setAttrs(newPlant)
            zw.setPoint(data["data"]["point"])
            zw.start()
            self.plant.add(zw)

    def sunShineFromPlayer(self, data):
        """收取阳光"""
        # data = {
        #     "act": "sunshine",
        #     "guid": "2dac8c68-7273-11ef-af9d-0242ac120006",
        #     "data": { "atk": 30 },
        # }

        sun = self.onlyFindStarForGuid(data["target"])
        if not sun:
            return
        self.money += data["data"]["atk"]
        self.alertAIring(
            {"act": "sunShine", "guid": data["target"], "data": data["data"]["atk"]}
        )
        # self.sunlight.remove(sun)
        sun.stop()
        sun.join()

    def newStarFromPlant(self, data):
        """创建星星"""
        xx = moneyStar(self)
        xx.setAttrs(data)
        xx.setPoint((0, random.choice(range(7))))
        xx.start()
        self.sunlight.add(xx)

    def newSlugFromPlant(self, data, point):
        """创建子弹"""
        print(data, point)
        zd = fireSlug(self)
        zd.setAttrs(data)
        zd.setPoint(point)
        zd.start()
        self.slug.add(zd)

    # ----------------------------------------------
    def onlyFindStarForGuid(self, guid):
        """通过guid查找阳光"""
        for sun in self.sunlight:
            if sun.guid == guid:
                return sun
        else:
            return None
